'''
This application is used to evaluate the performance of the solution:

1. latency with x(path), y(delay), 3pics, dense, sparse, trace
2. packet  with x(path), y(packet), 3pics, dense, sparse, trace
'''
import os, random, datetime, subprocess, time
import sys
sys.path.append('/opt/sumo/sumo-0.17.1/tools')
import sumolib
import trace

class NetSimu:
    def __init__(self, netf, tracef):
        self.TRANGE = 100
        
        print "loading..."
        self._tracef = tracef
        self._netf = netf
        self._net = sumolib.net.readNet(self._netf)
        self._trace = trace.readTrace(self._tracef)
        print "done..."
    
    def Eval(self, length):
        self._totaltime = 0
        self._totalpacket = 0
        self._totallength = 0
        while self._totallength < length:
            # select a random snapshot
            rSnap = random.choice(self._trace.getSnapshots())
            # select a random road
            rRoadName = random.choice(rSnap.getEdges().keys())
            #print rRoadName
            if rRoadName.startswith(":"):
                continue
            
            rRoadInfo = self._net.getEdge(rRoadName)
            rRoadSnap = rSnap.getEdges()[rRoadName]
            
            self.CollectEdge(rRoadInfo, rRoadSnap)
        # end while
        

    def CollectEdge(self, roadInfo, roadSnap):
        #roadSnap.dump()
        maxspeed = roadInfo.getSpeed()
        maxlen = roadInfo.getLength()
        curlen = 0
        curspeed = maxspeed
        
        while curlen < maxlen:
            # next hop vehicle.
            g = lambda x: x.getPos() < curlen + self.TRANGE and x.getPos() > curlen
            nhv =  filter(g, roadSnap.getVehicles().values())
            #print nhv
            if len(nhv) == 0: #no next hop
                #curspeed = (curspeed + maxspeed)/2
                curlen += curspeed
                self._totaltime += 0.8
                self._totalpacket += 1
            else:
                self._totalpacket += (len(nhv) + 1)
                curlen = max([pos.getPos() for pos in nhv])
                curspeed = max([pos.getSpeed() for pos in nhv])
                if curspeed == 0: curspeed = maxspeed
                # self._totaltime += 0.1
            #end if
            
            #print "curlen = %d, maxlen = %d" % (curlen, maxlen)
        # end while
        self._totallength += maxlen
        
        
def EvalTestbed():
    path = '/Users/hezongjian/Documents/texsrc/Traffic/simu/testbed/'
    simud = NetSimu(path +'testbed.net.xml', path + 'dense.netstate.xml')
    drst = []
    
    for l in range(10000, 200000, 20000):
        simud.Eval(l)
        print "Len = %d, Total time = %d, total packet = %d" % (l, simud._totaltime, simud._totalpacket)
        drst.append([l, simud._totaltime, simud._totalpacket])
    #end for
    with open('./net.desne.txt', 'w') as f:
        for v in drst:
            opt = "%d, %d, %d\r\n" % (v[0], v[1], v[2])
            print opt,
            f.write(opt)
        
    simus = NetSimu(path +'testbed.net.xml', path + 'sparse.netstate.xml')
    srst = []
    
    for l in range(10000, 200000, 20000):
        simus.Eval(l)
        print "Len = %d, Total time = %d, total packet = %d" % (l, simud._totaltime, simud._totalpacket)
        srst.append([l, simus._totaltime, simus._totalpacket])
    #end for
    with open('./net.sparse.txt', 'w') as f:
        for v in srst:
            opt = "%d, %d, %d\r\n" % (v[0], v[1], v[2])
            print opt,
            f.write(opt)



def EvalTrace():
    path = '/Users/hezongjian/Documents/texsrc/Traffic/simu/trace/'
    simud = NetSimu(path +'cologne.net.xml', path + 'netstate.xml')
    drst = []
    
    for l in range(10000, 200000, 20000):
        simud.Eval(l)
        print "Len = %d, Total time = %d, total packet = %d" % (l, simud._totaltime, simud._totalpacket)
        drst.append([l, simud._totaltime, simud._totalpacket])
    #end for
    with open('./net.trace.txt', 'w') as f:
        for v in drst:
            opt = "%d, %d, %d\r\n" % (v[0], v[1], v[2])
            print opt,
            f.write(opt)


def main():
    print "hello";
    #EvalTestbed()
    EvalTrace()


if __name__ == "__main__":
    start = time.clock()
    random.seed(123456)
    main()
    elapsed = (time.clock() - start)
    print "Time used: %.2f" % elapsed